home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / Beer Goggles Hack / mac / main.c < prev   
Encoding:
Text File  |  2001-06-23  |  12.4 KB  |  610 lines

  1. /*
  2.     File:        HackTV.c
  3.  
  4.     Contains:    Hack TV routines.
  5.             
  6.                 Refer to develop Issue 14, "Video Digitizing Under QuickTime",
  7.                 for details on this code.
  8.                 
  9.     Written by:    Gary Woodcock
  10.     Updated by: Brian Friedkin
  11.  
  12.     Copyright:    © 1992-1998 by Apple Computer, Inc.
  13. */
  14.  
  15. //-----------------------------------------------------------------------
  16. // Includes
  17. #include <QTML.h>
  18. #include <Menus.h>
  19. #include <MacWindows.h>
  20. #include <QuickDraw.h>
  21. #include <Resources.h>
  22. #include <Fonts.h>
  23. #include <ToolUtils.h>
  24. #include <QuickTimeComponents.h>
  25. #include <Scrap.h>
  26. #include <Printing.h>
  27. #include <Errors.h>
  28. #include <Folders.h>
  29. #include <Script.h>
  30. #include <MacMemory.h>
  31. #include <Gestalt.h>
  32. #include <Endian.h>
  33. #include <Devices.h>
  34. #include <LowMem.h>
  35. #include <TextUtils.h>
  36. #include <profiler.h>
  37. #include "Globals.h"
  38. #include "Common.h"
  39.  
  40. #define kMenuBarID 128
  41. enum
  42. {
  43.     kAppleID = 128,
  44.     kFileID,
  45.     kEditID,
  46.     kMonitorID
  47. };
  48.     
  49. // Apple menu items
  50. enum
  51. {
  52.     kAboutItem = 1
  53. };
  54.  
  55. // File menu items
  56. enum
  57. {
  58.     kPageSetupItem = 1,
  59.     kPrintItem,
  60.     kQuitItem = 4
  61. };
  62.  
  63. // Edit menu items
  64. enum
  65. {
  66.     kUndoItem = 1,
  67.     kCutItem = 3,
  68.     kCopyItem,
  69.     kPasteItem,
  70.     kClearItem
  71. };
  72.  
  73. // Monitor menu items
  74. enum
  75. {
  76.     kVideoSettingsItem = 1,
  77.     kSoundSettingsItem,
  78.     kRecordVideoItem = 4,
  79.     kRecordSoundItem,
  80.     kSplitTracksItem,
  81.     kQuarterSizeItem = 8,
  82.     kHalfSizeItem,
  83.     kFullSizeItem,
  84.     kRecordItem = 12,
  85.     kColorPicker = 13
  86. };
  87.     
  88. //-----------------------------------------------------------------------
  89. // Globals
  90. MenuHandle                gAppleMenu=0;
  91. MenuHandle                gFileMenu=0;
  92. MenuHandle                gEditMenu=0;
  93. MenuHandle                gMonitorMenu=0;
  94. EventRecord                gTheEvent;
  95. extern RGBColor gColorToReplace;
  96. extern RGBColor gColorToReplaceWith;
  97. extern Boolean    gParental;
  98.  
  99. //-----------------------------------------------------------------------
  100. // Prototypes
  101. static void Initialize (void);
  102. static void DoMenuSetup (void);
  103. static void HandleEvent (void);
  104. static void HandleMouseDown    (void);
  105. static void AdjustMenus (void);
  106. static void Enable (Handle menu, short item, Boolean ok);
  107. static void HandleMenu (long menu);
  108. static void DoQuit (void);
  109.  
  110. Boolean WaitNextEventWrapper ( EventMask      eventMask,
  111.   EventRecord *  theEvent,
  112.   UInt32         sleep,
  113.   RgnHandle      mouseRgn);
  114. ComponentResult SGIdleWrapper (SeqGrabComponent s);
  115. ComponentResult SGUpdateWrapper (SeqGrabComponent s, RgnHandle updateRgn);
  116.  
  117. //-----------------------------------------------------------------------
  118.  
  119. void main (void)
  120. {
  121.     Initialize();
  122.     
  123.     #if __profile__
  124.     {
  125.         OSErr    oseProfile;
  126.         oseProfile = ProfilerInit (collectDetailed, bestTimeBase, 100, 1000);
  127.     }
  128.     #endif
  129.  
  130.     // Eat events until done
  131.     do
  132.     {
  133.         HandleEvent();
  134.     }
  135.     while (!gQuitFlag);
  136.     
  137.     #if __profile__
  138.     {
  139.         OSErr    oseProfile;
  140.         oseProfile = ProfilerDump ("\pHack Profile");
  141.         ProfilerTerm ();
  142.     }
  143.     #endif
  144. }
  145.  
  146. //-----------------------------------------------------------------------
  147.  
  148. void Initialize(void)
  149. {
  150.     EventRecord event;
  151.     short    count;
  152.  
  153.     // Stock initialization
  154.     InitGraf((Ptr) &qd.thePort);
  155.     InitFonts();
  156.     InitWindows();
  157.     InitMenus();
  158.     TEInit();
  159.     InitDialogs(nil);
  160.     InitCursor();
  161.     MaxApplZone();
  162.     for (count = 1; count <= 3; count++)
  163.         EventAvail(everyEvent, &event);
  164.  
  165.     // Load the menubar
  166.     DoMenuSetup();
  167.  
  168.     // Initialize QuickTime
  169.     EnterMovies();
  170.     
  171.     // Startup the sequence grabber
  172.     InitializeSequenceGrabber();
  173. }
  174.  
  175. //-----------------------------------------------------------------------
  176.  
  177. void CreateMonitorWindow(void)
  178. {
  179.     gMonitor = GetNewDialog (kMonitorDLOGID, nil, (WindowPtr) -1L);
  180. }
  181.  
  182. //-----------------------------------------------------------------------
  183.  
  184. static void
  185. DoMenuSetup (void)
  186. {    
  187.     Handle    theMenuBar = GetNewMBar (kMenuBarID);
  188.     
  189.     // Set up our menus
  190.     SetMenuBar (theMenuBar);
  191.     gAppleMenu = GetMenuHandle (kAppleID);
  192.     gFileMenu = GetMenuHandle (kFileID);
  193.     gEditMenu = GetMenuHandle (kEditID);
  194.     gMonitorMenu = GetMenuHandle (kMonitorID);
  195.     AppendResMenu (gAppleMenu, 'DRVR');
  196.     
  197.     // Last minute adjustments…
  198.     AdjustMenus();
  199. }
  200.  
  201. //-----------------------------------------------------------------------
  202.  
  203. static void
  204. HandleEvent (void)
  205. {
  206.     ComponentResult    result = noErr;
  207.     static unsigned long    oldTicks = 0;
  208.  
  209.     // Do system stuff
  210.     HiliteMenu(0);
  211.     SystemTask();
  212.     
  213.     // Give some time to the sequence grabber
  214.     if (gSeqGrabber != 0L)
  215.         result = SGIdleWrapper (gSeqGrabber);
  216.     
  217.     if ((TickCount () - oldTicks) >= 2) {
  218.         GrafPtr    oldPort;
  219.         Rect    rBounds;
  220.         GetPort (&oldPort);
  221.         SetPort (gMonitor);
  222.         rBounds = gMonitor->portRect;
  223.         OffsetRect (&rBounds, -rBounds.left, -rBounds.top);
  224.         InvalRect (&gMonitor->portRect);
  225.         SetPort (oldPort);
  226.         oldTicks = TickCount ();
  227.     }
  228.  
  229.     // Suck an event
  230.     if (WaitNextEventWrapper (everyEvent, &gTheEvent, 0, 0))
  231.     {
  232.         // What was it?
  233.         switch (gTheEvent.what)
  234.         {
  235.             case mouseDown:
  236.             {
  237.                 // Handle it
  238.                 HandleMouseDown();
  239.                 break;
  240.             }
  241.             case keyDown:
  242.             case autoKey:
  243.             {
  244.                 char    theChar = gTheEvent.message & charCodeMask;
  245.                 long    theMenu = MenuKey (theChar);
  246.  
  247.                 // Handle menu command keys
  248.                 HandleMenu(theMenu);                
  249.                 break;
  250.             }
  251.             case updateEvt:
  252.             {
  253.                 if ((gMonitor != nil) && ((WindowPtr) (gTheEvent.message) == (WindowPtr) gMonitor))
  254.                 {
  255. //                    SGUpdateWrapper (gSeqGrabber, ((WindowPeek)gMonitor)->updateRgn);
  256.                     BeginUpdate (gMonitor);
  257.                     CopyFrameToWindow (gMonitor);
  258.                     EndUpdate (gMonitor);
  259.                 }
  260.                 break;
  261.             }
  262.  
  263.             default:    // We don't really care about any other events, but you might, so feel free
  264.             {
  265.                 break;
  266.             }
  267.         }
  268.     }
  269.     
  270. }
  271.  
  272.  
  273. // Wrapper for WaitNextEvent so we can profile it
  274. Boolean WaitNextEventWrapper ( EventMask      eventMask,
  275.   EventRecord *  theEvent,
  276.   UInt32         sleep,
  277.   RgnHandle      mouseRgn)
  278. {
  279.     WaitNextEvent (eventMask, theEvent, sleep, mouseRgn);
  280. }
  281.  
  282.  
  283. // Wrapper for SGIdle so we can profile it
  284. ComponentResult SGIdleWrapper (SeqGrabComponent s)
  285. {
  286.     SGIdle (s);
  287. }
  288.  
  289.  
  290. // Wrapper for SGUpdate so we can profile it
  291. ComponentResult SGUpdateWrapper (SeqGrabComponent s, RgnHandle updateRgn)
  292. {
  293.     SGUpdate (s, updateRgn);
  294. }
  295.  
  296. //-----------------------------------------------------------------------
  297.  
  298. static void
  299. HandleMouseDown (void)
  300. {    
  301.     WindowPtr    theWindow;
  302.     short        windowCode = MacFindWindow (gTheEvent.where, &theWindow);
  303.     
  304.     // Where was the mouse down?
  305.     switch (windowCode)
  306.     {
  307.         case inSysWindow:
  308.         { 
  309.             SystemClick (&gTheEvent, theWindow);
  310.             break;
  311.         }
  312.         case inMenuBar:
  313.         {
  314.             AdjustMenus();
  315.             HandleMenu (0L);
  316.             break;
  317.         }
  318.         case inDrag:
  319.         {
  320.             // Was it the monitor?
  321.             if (theWindow == gMonitor)
  322.             {
  323.                 ComponentResult    result = noErr;
  324.                 Rect            limitRect;
  325.                 RgnHandle        grayRgn = GetGrayRgn();
  326.                 Rect            boundsRect;
  327.                 
  328.                 // Find bounds
  329.                 if (grayRgn != nil)
  330.                 {
  331.                     limitRect = (*grayRgn)->rgnBBox;
  332.                 }
  333.                 else
  334.                 {
  335.                     limitRect = qd.screenBits.bounds;
  336.                 }
  337.                 
  338.                 // Pause the sequence grabber
  339.                 result = SGPause (gSeqGrabber, true);
  340.                 
  341.                 if (gVideoChannel != nil)
  342.                 {
  343.                     // Drag it with the totally cool DragAlignedWindow
  344.                       result = SGGetChannelBounds (gVideoChannel, &boundsRect);
  345.                     DragAlignedWindow (theWindow, gTheEvent.where, &limitRect, &boundsRect, &gSeqGrabberAlignProc);
  346.                 }
  347.                 else
  348.                 {
  349.                     DragWindow (theWindow, gTheEvent.where, &limitRect);
  350.                 }
  351.                 
  352.                 // Start up the sequence grabber
  353.                 result = SGPause (gSeqGrabber, false);
  354.             }
  355.             break;
  356.         }
  357.  
  358.         case inGoAway:
  359.               if (TrackGoAway(theWindow, gTheEvent.where))
  360.                 DoQuit();
  361.             break;
  362.  
  363.         default:
  364.         {
  365.             break;
  366.         }
  367.     }
  368. }
  369.  
  370. //-----------------------------------------------------------------------
  371.  
  372. static void
  373. AdjustMenus (void)
  374. {
  375.     register WindowPeek        wp = nil;
  376.     short                    kind = 0;
  377.     Boolean                    DA = false;
  378.     ComponentResult            result = noErr;
  379.     
  380.     // What kind of window is frontmost?
  381.     wp = (WindowPeek) FrontWindow();
  382.     kind = wp ? wp->windowKind : 0;
  383.     DA = kind < 0;
  384.     
  385.     // Set our menu item states appropriately
  386.     
  387.     // Apple menu
  388.     Enable ((Handle) gAppleMenu, kAboutItem, true);    
  389.     
  390.     // File menu
  391.     Enable ((Handle) gFileMenu, kPageSetupItem, true);
  392.     Enable ((Handle) gFileMenu, kPrintItem, (gVideoChannel != 0L ? true : false));
  393.     Enable ((Handle) gFileMenu, kQuitItem, true);
  394.  
  395.     // Edit menu
  396.     Enable ((Handle) gEditMenu, kUndoItem, DA);
  397.     Enable ((Handle) gEditMenu, kCutItem, DA || (gVideoChannel != 0L));
  398.     Enable ((Handle) gEditMenu, kCopyItem, DA || (gVideoChannel != 0L));
  399.     Enable ((Handle) gEditMenu, kPasteItem, DA);
  400.     Enable ((Handle) gEditMenu, kClearItem, DA);
  401.     
  402.     // Monitor menu
  403.     Enable ((Handle) gMonitorMenu, kVideoSettingsItem, (gVideoChannel != 0L ? true : false));
  404.     Enable ((Handle) gMonitorMenu, kSoundSettingsItem, (gSoundChannel != 0L ? true : false));
  405.  
  406.     Enable ((Handle) gMonitorMenu, kRecordVideoItem, (gVideoChannel != 0L ? true : false));
  407.     CheckItem (gMonitorMenu, kRecordVideoItem, (gVideoChannel && gRecordVideo)? true : false );
  408.     Enable ((Handle) gMonitorMenu, kRecordSoundItem, (gSoundChannel != 0L ? true : false));
  409.     CheckItem (gMonitorMenu, kRecordSoundItem, (gSoundChannel && gRecordSound)? true : false );
  410.      Enable ((Handle) gMonitorMenu, kSplitTracksItem, (gSoundChannel && gRecordSound && gVideoChannel && gRecordVideo)? true : false);
  411.      CheckItem (gMonitorMenu, kSplitTracksItem, gSplitTracks ? true : false);
  412.  
  413.     Enable ((Handle) gMonitorMenu, kQuarterSizeItem, (gVideoChannel != 0L ? true : false));
  414.     CheckItem (gMonitorMenu, kQuarterSizeItem, gQuarterSize);
  415.     Enable ((Handle) gMonitorMenu, kHalfSizeItem, (gVideoChannel != 0L ? true : false));
  416.     CheckItem (gMonitorMenu, kHalfSizeItem, gHalfSize);
  417.     Enable ((Handle) gMonitorMenu, kFullSizeItem, (gVideoChannel != 0L ? true : false));
  418.     CheckItem (gMonitorMenu, kFullSizeItem, gFullSize);
  419.     Enable ((Handle) gMonitorMenu, kRecordItem, ((gSoundChannel && gRecordSound) || (gVideoChannel && gRecordVideo) ? true : false));
  420.     
  421.     CheckItem (gMonitorMenu, 15, gParental);
  422.     // Draw it
  423.     MacDrawMenuBar();
  424. }
  425.  
  426. //-----------------------------------------------------------------------
  427.  
  428. static void
  429. Enable (Handle menu, short item, Boolean ok)
  430. {
  431.     // Utility routine to enable and disable menu items
  432.     if (ok)
  433.     {
  434.         EnableItem ((MenuHandle) menu, item);
  435.     }
  436.     else
  437.     {
  438.         DisableItem ((MenuHandle) menu, item);
  439.     }
  440. }
  441.  
  442. //-----------------------------------------------------------------------
  443.  
  444. static void
  445. HandleMenu (long theMenu)
  446. {    
  447.     long            mSelect;
  448.     short            menuID;
  449.     short            menuItem;
  450.     ComponentResult    result = noErr;    
  451.     
  452.     // Did we get a menu?
  453.     if (theMenu == 0L)
  454.     {
  455.         // Nope, get it from menu select
  456.         mSelect = MenuSelect (gTheEvent.where);
  457.     }
  458.     else
  459.     {
  460.         // Yep, use it
  461.         mSelect = theMenu;
  462.     }
  463.     
  464.     // Decode it
  465.     menuID = HiWord (mSelect);
  466.     menuItem = LoWord (mSelect);
  467.     
  468.     // Which menu is it?
  469.     switch (menuID)
  470.     {
  471.         case kAppleID:
  472.         {
  473.             if (menuItem == kAboutItem)
  474.             {
  475.                 // Do the boring about box
  476.                 DoAboutDialog();
  477.             }
  478.             else    // It's a DA
  479.             {
  480.                 Str255    name;
  481.                 GrafPtr    savedPort;
  482.                 
  483.                 // Open the DA
  484.                 GetPort (&savedPort);
  485.                 GetMenuItemText (gAppleMenu, menuItem, name);
  486.                 OpenDeskAcc (name);
  487.                 SetPort (savedPort);
  488.             }
  489.             break;
  490.         }
  491.         case kFileID:
  492.         {
  493.             switch (menuItem)
  494.             {
  495.                 case kPageSetupItem:
  496.                     DoPageSetup();
  497.                     break;
  498.  
  499.                 case kPrintItem:
  500.                     DoPrint();
  501.                     break;
  502.                     
  503.                 case kQuitItem:
  504.                     DoQuit();
  505.                     break;
  506.             }
  507.             break;
  508.         }
  509.         case kEditID:
  510.         {
  511.             // Is this a DA kind of thing?
  512.             if (!SystemEdit (menuItem - 1))
  513.             {
  514.                 // We only do cut and copy
  515.                 if ((menuItem == kCutItem) || (menuItem == kCopyItem))
  516.                     DoCopyToClipboard();
  517.             }
  518.             break;
  519.         }
  520.         case kMonitorID:
  521.         {
  522.             switch (menuItem)
  523.             {
  524.                 case kVideoSettingsItem:
  525.                     DoVideoSettings();
  526.                     break;
  527.  
  528.                 case kSoundSettingsItem:
  529.                     DoSoundSettings();
  530.                     break;
  531.  
  532.                 case kRecordVideoItem:
  533.                     gRecordVideo = !gRecordVideo;
  534.                     AdjustMenus();
  535.                     break;
  536.  
  537.                 case kRecordSoundItem:
  538.                     gRecordSound = !gRecordSound;
  539.                     AdjustMenus();
  540.                     break;
  541.  
  542.                 case kSplitTracksItem:
  543.                     gSplitTracks = !gSplitTracks;
  544.                     AdjustMenus();
  545.                     break;
  546.  
  547.                 case kQuarterSizeItem:
  548.                     DoResize(4);
  549.                     break;
  550.  
  551.                 case kHalfSizeItem:
  552.                     DoResize(2);
  553.                     break;
  554.                     
  555.                 case kFullSizeItem:
  556.                     DoResize(1);
  557.                     break;
  558.                     
  559.                 case kRecordItem:
  560.                     DoRecord();
  561.                     break;
  562.                 
  563.                 case kColorPicker:
  564.                     GetSkinTone (&gColorToReplace);
  565.                 break;
  566.                 
  567.                 case 14:
  568.                     GetSkinTone (&gColorToReplaceWith);
  569.                 break;
  570.                 
  571.                 case 15:
  572.                     ToggleParentalFilter ();
  573.                 break;
  574.  
  575.                 default:
  576.                     break;
  577.             }
  578.         }
  579.         default:
  580.             break;
  581.     }
  582. }
  583.  
  584. //-----------------------------------------------------------------------
  585.  
  586. static void
  587. DoQuit (void)
  588. {
  589.     ComponentResult    result = noErr;
  590.     
  591.     // Clean up
  592.     if (gSeqGrabber != 0L)
  593.     {
  594.         result = CloseComponent (gSeqGrabber);
  595.         gSeqGrabber = 0L;
  596.     }    
  597.     
  598.     if (gMonitor != nil)
  599.     {
  600.         DisposeWindow(gMonitor);
  601.     }
  602.     
  603.     // Set quit flag
  604.     gQuitFlag = true;
  605.     
  606.     ExitMovies();
  607. }
  608.  
  609. //-----------------------------------------------------------------------
  610.